<?php

namespace app\api\controller\Course;

use app\api\controller\Common;
use app\api\Logic\Campusclass\CampusClassLogic;
use app\api\Logic\Course\MallGoodsLogic;
use app\api\Logic\Course\ManagementPackageOrderLogic;
use app\api\Logic\Goods\CampusGoodsLogic;
use app\api\Logic\Pay\PayLogic;
use app\api\model\CampusCourseOrderModel;
use app\api\model\CampusCourseOrderSublevelModel;
use think\Db;
use think\Exception;

/**
 * 套餐课程订单接口
 */
class ManagementPackageOrder extends Common
{
    protected $noNeedLogin = ['*'];

    protected $mallGoodsLogic;
    protected $managementPackageOrderLogic;
    protected $payLogic;
    protected $campusGoodsLogic;
    protected $campusClassLogic;

    public function _initialize()
    {
        parent::_initialize();
        $this->mallGoodsLogic = new MallGoodsLogic();
        $this->managementPackageOrderLogic = new ManagementPackageOrderLogic();
        $this->payLogic = new PayLogic();
        $this->campusGoodsLogic = new CampusGoodsLogic();
        $this->campusClassLogic = new CampusClassLogic();
    }

    /**
     * 订单整理
     */
    public function collation(){
        if($this->request->isPost()){
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            $mallGoodsId = $param['mall_goods_id'] ?? 0;
            if(empty($mallGoodsId)){
                $this->error('选课ID必须');
            }

            //获取选课详情
            $info = $this->mallGoodsLogic->info($param['shop_id'],$mallGoodsId);
            if(empty($info)){
                $this->error('信息不存在');
            }
            //若选课不为套餐类型，则提示异常，该接口仅给套餐订单调用
            if($info['type'] != 2){
                $this->error('接口调用错误');
            }

            /**
             * 由于物品存在规格选择，因此下单套餐课程时需提供选择的规格id
             * 只有当存在规格商品时goods_list字段才有值
             * $goodsList = [
             *      ['goods_id' => 1,'spec_ids' => [1,2]],
             *      ['goods_id' => 2,'spec_ids' => [3,4]],
             *      ...
             * ]
             */
            $goodsList = $param['goods_list'] ?? [];
            if(!empty($goodsList)){
                $goodsList = array_column($goodsList,null,'goods_id');
            }

            //套餐内商品列表
            $managementPackageGoodsList = $info['management_package_info']['goods_list'] ?? [];
            $courseIds = [];
            foreach ($managementPackageGoodsList as $goodsInfo){
                //套餐内存在物品
                if($goodsInfo['type'] == 1){
                    if(!isset($goodsList[$goodsInfo['gs_id']])){
                        $this->error('请选择物品规格');
                    }

                    $specList = $goodsInfo['goods_info']['spec_list'] ?? [];
                    $specList = objToArray($specList);

                    $selectSpec = $goodsList[$goodsInfo['goods_info']['id']]['spec_ids'] ?? [];
                    //当套餐内物品存在规格时，用户未选规格提示
                    if(!empty($specList) && (empty($goodsList) || empty($selectSpec))){
                        $this->error('请选择物品规格');
                    }
                }else if($goodsInfo['type'] == 3){
                    //套餐内存在课程
                    $courseIds[] = $goodsInfo['gs_id'];
                }
            }

            //可选班级列表，根据课程获取班级列表，再根据班级的is_choose判断是否可选
            $classList = $this->campusClassLogic->getClassByCourseIds($param['shop_id'],$courseIds);
            if(!empty($classList)){
                foreach ($classList as $classInfo){
                    if($classInfo['is_choose'] == 1){
                        $info['class_list'][] = $classInfo;
                    }
                }
            }

            //todo 本次可使用优惠券信息，暂未实现该接口，默认空数组
            $info['coupon_list'] = [];

            //todo 课程顾问信息，暂未实现该接口，默认空数组
            $info['course_adviser'] = [];

            if(!empty($info)){
                $this->success('查询成功',$info);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }

    /**
     * 创建订单
     */
    public function create(){
        if($this->request->isPost()){
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            $mallGoodsId = $param['mall_goods_id'] ?? 0;
            if(empty($mallGoodsId)){
                $this->error('选课ID必须');
            }

            if(!isset($param['pay_type']) || !isset($this->payTypeMap()[$param['pay_type']])){
                $this->error('支付方式不可用');
            }

            //获取选课详情
            $info = $this->mallGoodsLogic->info($param['shop_id'],$mallGoodsId);
            if(empty($info)){
                $this->error('信息不存在');
            }
            //若选课不为套餐类型，则提示异常，该接口仅给套餐订单调用
            if($info['type'] != 2){
                $this->error('接口调用错误');
            }

            /**
             * 由于物品存在规格选择，因此下单套餐课程时需提供选择的规格id
             * 只有当存在规格商品时goods_list字段才有值
             * $goodsList = [
             *      ['goods_id' => 1,'spec_ids' => [1,2]],
             *      ['goods_id' => 2,'spec_ids' => [3,4]],
             *      ...
             * ]
             */
            $goodsList = $param['goods_list'] ?? [];
            if(!empty($goodsList)){
                $goodsList = array_column($goodsList,null,'goods_id');
            }

            //套餐内商品列表
            $managementPackageGoodsList = $info['management_package_info']['goods_list'] ?? [];
            foreach ($managementPackageGoodsList as $goodsInfo){
                //套餐内存在物品
                if($goodsInfo['type'] == 1){
                    if(!isset($goodsList[$goodsInfo['gs_id']])){
                        $this->error('请选择物品规格');
                    }

                    $specList = $goodsInfo['goods_info']['spec_list'] ?? [];
                    $specList = objToArray($specList);

                    $selectSpec = $goodsList[$goodsInfo['goods_info']['id']]['spec_ids'] ?? [];
                    //当套餐内物品存在规格时，用户未选规格提示
                    if(!empty($specList) && (empty($goodsList) || empty($selectSpec))){
                        $this->error('请选择物品规格');
                    }
                }
            }

            Db::startTrans();
            try {
                $orderInfo = [
                    'no' => date("YmdHis") . mt_rand(100000, 999999),
                    'shop_id' => $param['shop_id'],
                    'user_id' => $param['user_id'],
                    'style' => 2,
                    'goods_id' => $mallGoodsId,
                    'price' => $info['price'] ?? 0,
                    'name' => $info['name'],
                    'image' => $info['image'],
                    'status' => 1,
                    'createtime' => time()
                ];

                $orderId = CampusCourseOrderModel::insertGetId($orderInfo);

                //生成订单子项
                $packageGoodsList = $info['management_package_info']['goods_list'] ?? [];
                foreach ($packageGoodsList as $packageGoods){
                    $tempData = [
                        'no' => $orderInfo['no'],
                        'shop_id' => $param['shop_id'],
                        'user_id' => $param['user_id'],
                        'type' => $packageGoods['type'],
                        'gs_id' => $packageGoods['id'],
                        'num' => 1,
                        'price' => $packageGoods['pricing'],
                        'use_num' => 0,
                        'status' => 0,  //未支付成功状态都为0
                    ];
                    if($packageGoods['type'] == 3){
                        //子项为课程
                        $givingNum = 0; //todo 赠送课时数
                        $givingType = ''; //todo 赠送课时类型
                        if($packageGoods['goods_info']['hour_status'] == 1){
                            $mType = 'hour';
                            //由于套餐内课时无法选择，因此默认第一个数据
                            $mTypeNum = $packageGoods['goods_info']['hour'][0]['num'] ?? 0;
                        }else if($packageGoods['goods_info']['monthly_status'] == 1){
                            $mType = 'monthly';
                            //由于套餐内课时无法选择，因此默认第一个数据
                            $mTypeNum = $packageGoods['goods_info']['monthly'][0]['num'] ?? 0;
                        }else if($packageGoods['goods_info']['per_diem_status'] == 1){
                            $mType = 'monthly';
                            //由于套餐内课时无法选择，因此默认第一个数据
                            $mTypeNum = $packageGoods['goods_info']['day'][0]['num'] ?? 0;
                        }
                        $tempData['m_type'] = $mType;
                        $tempData['m_type_num'] = $mTypeNum;
                        $allNum = $mTypeNum + $givingNum; //总课时数
                        $tempData['giving'] = $givingNum;
                        $tempData['giving_type'] = $givingType;
                        $tempData['all_num'] = $allNum;
                        //所选班级ID
                        $tempData['class_ids'] = $param['class_id'] ?? 0;
                    }else if($packageGoods['type'] == 1){
                        //子项为物品
                        $specIds = $goodsList[$packageGoods['goods_info']['id']]['spec_ids'] ?? [];
                        $specName = [];
                        foreach ($specIds as $specId){
                            $specInfo = $this->campusGoodsLogic->getSpecNameBySpecId($specId);
                            if(isset($specInfo['value_name']) && !empty($specInfo['value_name'])){
                                $specName[] = $specInfo['value_name'];
                            }
                        }
                        $tempData['spec_id'] = !empty($specIds) ? implode('_',$specIds) : '';
                        $tempData['spec_name'] = !empty($specName) ? implode('+',$specName) : '';
                    }
                    CampusCourseOrderSublevelModel::insert($tempData);
                }


                //订单金额
                $orderMoney = $orderInfo['price'];
                //优惠金额
                $discountMoney = $param['coupon_amount'] ?? 0;
                //实付金额 = 订单金额 - 优惠券抵扣金额
                $payMoney = round($orderMoney - $discountMoney,2);

                //创建主订单记录
                $this->payLogic->createOrder([
                    'shop_id' => $param['shop_id'],
                    'controller' => 'course/management_package_order',
                    'order_sn' => $orderInfo['no'],
                    'order_id' => $orderId,
                    'user_id' => $param['user_id'],
                    'price' => $orderMoney,
                    'coupon_id' => $param['coupon_id'] ?? 0,
                    'coupon_amount' => $discountMoney,
                    'pay_type' => $param['pay_type'] == 1 ? 'wechat' : ($param['pay_type'] == 2 ? 'alipay' : ''),
                    'real_price' => $payMoney,
                    'pay_amount' => $payMoney,
                    'status' => 0,
                    'createtime' => time()
                ]);

                //如果套餐价格为0，则直接支付成功
                $payStatus = 1; //待支付
                if($payMoney == 0){
                    //执行支付成功回调
                    $res = $this->managementPackageOrderLogic->payment(
                        [
                            'out_trade_no' => $orderInfo['no']
                        ]
                    );
                    if($res){
                        $payStatus = 2; //已支付
                    }
                }

                Db::commit();
                $this->success('下单成功',['order_id' => $orderId,'pay_status' => $payStatus]);
            }catch (Exception $e){
                Db::rollback();
                $this->error('下单失败');
            }
        }
        $this->error('请求错误');
    }

    /**
     * 微信支付回调
     * todo 需按实际情况修改
     */
    public function notify(){
        //todo 默认写法，需按实际情况修改
        $xmlInfo = file_get_contents("php://input");
        //xms转数组
        $notifyRes = $this->xmlToArray($xmlInfo);

        //todo 回调数据验签成功
        if(true){
            $res = $this->managementPackageOrderLogic->payment($notifyRes);
            if($res){
                echo 'success';
                exit;
            }
        }
        echo 'fail';
    }

    /**
     * 主订单支付回调,用于订单商品价格为0直接支付
     */
    public function pay_result(){
        $params = $this->request->param();

        $orderId = $params['order_id'] ?? 0;
        if(empty($orderId)){
            return false;
        }

        return $this->managementPackageOrderLogic->payLogNotify($orderId);
    }

    /**
     * 我的套餐课
     */
    public function orderList(){
        if($this->request->isPost()){
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            //获取我的套餐课课程列表
            $list = $this->managementPackageOrderLogic->orderList($param,true);

            if(!empty($list)){
                $this->success('查询成功',$list);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }
}
